#ifndef P2P_BASE_PORYPROXY_H_
#define P2P_BASE_PORYPROXY_H_

#include "base/sigslot.h"
#include "portinterface.h"

namespace base
{
	class Network;
}

namespace cricket
{
	class PortProxy : public PortInterface, public sigslot::has_slots<>
	{
	public:
		PortProxy() {}
		virtual ~PortProxy() {}

		PortInterface* impl() { return impl_; }
		void set_impl(PortInterface* port);

		virtual const std::string& Type() const;
		virtual base::Network* Network() const;

		virtual void SetIceProtocolType(IceProtocolType protocol);
		virtual IceProtocolType IceProtocol() const;

		// Methods to get/set ICE role and tiebreaker values.
		virtual void SetRole(TransportRole role);
		virtual TransportRole Role() const;

		virtual void SetTiebreaker(uint64 tiebreaker);
		virtual uint64 Tiebreaker() const;

		virtual bool SharedSocket() const;

		// Forwards call to the actual Port
		virtual void PrepareAddress();
		virtual Connection* CreateConnection(const Candidate& remote_candidate, 
			CandidateOrigin origin);
		virtual Connection* GetConnection(const base::SocketAddress& remote_addr);

		virtual int SendTo(const void* data, size_t size, 
			const base::SocketAddress& addr, bool payload);
		virtual int SetOption(base::Socket::Option opt, int value);
		virtual int GetOption(base::Socket::Option opt, int* value);
		virtual int GetError();

		virtual const std::vector<Candidate>& Candidates() const;

		virtual void SendBindingResponse(StunMessage* request,
			const base::SocketAddress& addr);
		virtual void SendBindingErrorResponse(
			StunMessage* request, const base::SocketAddress& addr,
			int error_code, const std::string& reason);

		virtual void EnablePortPackets();

		virtual std::string ToString() const;

	private:
		void OnUnknownAddress(PortInterface* port,
			const base::SocketAddress &addr,
			ProtocolType proto,
			IceMessage *stun_msg,
			const std::string &remote_username,
			bool port_muxed);
		void OnRoleConflict(PortInterface* port);
		void OnPortDestroyed(PortInterface* port);

		PortInterface* impl_;
	}
}

#endif	// P2P_BASE_PORYPROXY_H_